package org.momo.rpc.protocol.codec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.extern.slf4j.Slf4j;
import org.momo.rpc.constant.SerializeKey;
import org.momo.rpc.extention.ExtensionLoader;
import org.momo.rpc.protocol.RpcMessage;
import org.momo.rpc.protocol.constant.ProtocolConstant;
import org.momo.rpc.serialize.Serializer;

import java.io.IOException;


@Slf4j
public class NettyEncodeHandler<T> extends MessageToByteEncoder<RpcMessage<T>> {
    @Override
    protected void encode(ChannelHandlerContext ctx, RpcMessage<T> rpcMessage, ByteBuf byteBuf) throws IOException {
        // get serializer
        String serializerKey = SerializeKey.getSerializerKeyByCode(rpcMessage.getHeader().getSerializer());
        Serializer serializer = ExtensionLoader.getExtensionLoader(Serializer.class).getExtension(serializerKey);

        // header
        RpcMessage.Header header = rpcMessage.getHeader();
        byteBuf.writeByte(ProtocolConstant.MAGIC);
        byteBuf.writeByte(ProtocolConstant.VERSION);
        byteBuf.writeByte(header.getSerializer());
        byteBuf.writeByte(header.getMessageType());
        byteBuf.writeByte(header.getStatus());
        byteBuf.writeLong(header.getId());

        // body
        byte[] data = serializer.serialize(rpcMessage.getData());
        int length = data.length;
        byteBuf.writeInt(length);
        byteBuf.writeBytes(data);

        log.debug("send message {}", rpcMessage);
    }

}
